<?php
/**
 * Used to grab the "Input" from HTTP (Get/Post/Request), and optionally filter it
 *
 * @author Highstrike (highstrike@gmail.com)
 * @author Wavetrex (wavetrex@gmail.com)
 * @package CargoClaims
 * @version 1.0.dev
 */
class MVC_Request
{
	const _REQUEST=0;
	const _GET=1;
	const _POST=2;
	const _COOKIE=3; // Read only (just like the other three) - Use MVC_Persist for the ability to write cookies as well

	/**
	 * Superglobal to use when reading values ( get / post / request )
	 * @var int
	 */
	private $_superglobal=self::_REQUEST;

	/**
	 * Initializes the request object using one of the superglobals as data source
	 * @param unknown_type $which_superglobal
	 */
	public function __construct($which_superglobal = "request")
	{
		$this-> set_Request_Type($which_superglobal);
	}

	/**
	 * List of filters that are applied to some input variables.
	 * Multiple filters can be applied on the same input variable !
	 * @var array
	 */
	private $_filters = array();

	/**
	 * Adds a filter on the input parameter, which will be applied when asking for the parameter
	 *
	 * @param string $parameter Used as key into the superglobal array
	 * @param string $filter_type What kind of filter?
	 * @param mixed $filter_cfg Other parameters for the filter (required only by some)
	 */
	public function add_Filter($parameter, $filter_type, $filter_cfg = null)
	{
		if(!isset($this->_filters[$parameter]))
			$this->_filters[$parameter] = array();
		// add each filter
		$this->_filters[$parameter][] = new MVC_Filter($filter_type, $filter_cfg);
	}

	/**
	 * Removes all filters, allowing setting new ones
	 *
	 * @param string $parameter
	 */
	public function clean_Filters($parameter)
	{
		unset($this->_filters[$parameter]);
	}

	/**
	 * Retrieves the content of a superglobal entry (if it exists), or null if it does not.
	 * Filters are only applied on an existing parameter
	 *
	 * @param string $name The input parameter contained in the set superglobal
	 * @return mixed
	 */
	public function __get($name)
	{
		switch($this->_superglobal) {
			case self::_REQUEST:
				if(!isset($_REQUEST[$name])) return null;
				$input = $_REQUEST[$name]; break;
			case self::_GET:
				if(!isset($_GET[$name])) return null;
				$input = $_GET[$name]; break;
			case self::_POST:
				if(!isset($_POST[$name])) return null;
				$input = $_POST[$name]; break;
			case self::_COOKIE:
				if(!isset($_COOKIE[$name])) return null;
				$input = $_COOKIE[$name]; break;
			default:
				throw new MVC_Exception("Unable to determine which Request superglobal is being used !");
		}

		if(isset($this->_filters[$name])) {
			// run all the filters on the input
			foreach($this->_filters[$name] as $filter)
				$input = $filter-> process($input);
		}
		return $input;
	}

	/**
	 * Checks if a superglobal entry exists
	 * @param string $name
	 * @return bool
	 */
	public function __isset($name)
	{
		switch($this->_superglobal) {
			case self::_REQUEST:
				return isset($_REQUEST[$name]);
			case self::_GET:
				return isset($_GET[$name]);
			case self::_POST:
				return isset($_POST[$name]);
			case self::_COOKIE:
				return isset($_COOKIE[$name]);
			default:
				throw new MVC_Exception("Unable to determine which Request superglobal is being used !");
		}
	}

	/**
	 * Return request array directly. Note that in this case filtering is NOT applied !
	 * @return array
	 */
	public function &request_toArray()
	{
		switch($this->_superglobal) {
			case self::_REQUEST:
				return $_REQUEST;
			case self::_GET:
				return $_GET;
			case self::_POST:
				return $_POST;
			case self::_COOKIE:
				return $_COOKIE;
			default:
				throw new MVC_Exception("Unable to determine which Request superglobal is being used !");
		}
	}

	/**
	 * Sets the type of request data to use when getting values
	 *
	 * @param string $superglobal
	 */
	public function set_Request_Type($superglobal='request')
	{
		switch(strtolower($superglobal)) {
			case 'request':
				$this->_superglobal=self::_REQUEST; break;
			case 'get':
				$this->_superglobal=self::_GET; break;
			case 'post':
				$this->_superglobal=self::_POST; break;
			case 'cookie':
				$this->_superglobal=self::_COOKIE; break;
		}
	}
}